import hashlib
import logging

from dtos.result import Result
from utils.common_util import CommonUtil


class ExternalApiCheck(object):

    def __init__(self, api_secret):
        self.api_secret = api_secret

    @classmethod
    def get_timestamp_and_sign(cls, **kwargs):
        sign, timestamp = kwargs.get("sign", None), kwargs.get("timestamp", None)
        if not sign:
            return Result.error_result(message="进行api check时没有找到sign")
        if not timestamp:
            return Result.error_result(message="进行api check时没有找到sign")
        del kwargs['sign']
        del kwargs['timestamp']
        return Result.success_result(data=(sign, timestamp, kwargs))

    @classmethod
    def encrypt(cls, **kwargs):
        key_list = list(kwargs)
        key_list.sort()
        encrypt_str = ""
        for key in key_list:
            if encrypt_str:
                encrypt_str += "&"
            encrypt_str += "%s=%s" % (key, kwargs[key])
        return encrypt_str

    def get_sign(self, encrypt_str, timestamp):
        logging.info("api_secret:%s" % self.api_secret)
        logging.info("encrypt_str:%s" % encrypt_str)
        logging.info("timestamp:%s" % timestamp)
        return hashlib.md5((self.api_secret + encrypt_str + str(timestamp)).encode()).hexdigest().upper()

    def check(self, **kwargs):
        get_res = self.get_timestamp_and_sign(**kwargs)
        if not get_res.is_success:
            return get_res
        sign, timestamp, data = get_res.data
        encrypt_str = self.encrypt(**data)
        new_sign = self.get_sign(encrypt_str, timestamp)
        sign, new_sign = str(sign).upper(), str(new_sign).upper()
        logging.info("本次收到的签名为：%s，本系统校验的签名为：%s" % (sign, new_sign))
        if sign != new_sign:
            return Result.error_result(message="错误的签名", code=303)
        if kwargs.get("timestamp"):
            del kwargs['timestamp']
        if kwargs.get("sign"):
            del kwargs['sign']
        return Result.success_result(data=kwargs)

    def get_params(self, **params):
        encrypt_str = self.encrypt(**params)
        encrypt_str = encrypt_str.replace("'", '"')
        encrypt_str = encrypt_str.replace(" ", "")
        logging.info("进行签名的参数：%s" % str(params))
        logging.info("待签名字符串：%s" % str(encrypt_str))
        timestamp = CommonUtil.get_timestamp_thirteen()
        sign = self.get_sign(encrypt_str, timestamp)
        logging.info("签名的结果：%s" % str(sign))
        params['timestamp'] = timestamp
        params['sign'] = sign
        return params
